package com.thesis.utils;

import cn.hutool.core.util.IdUtil;
import com.auth0.jwt.JWT;
import com.auth0.jwt.JWTVerifier;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.JWTDecodeException;
import com.auth0.jwt.exceptions.JWTVerificationException;
import com.auth0.jwt.interfaces.DecodedJWT;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

import java.io.UnsupportedEncodingException;
import java.util.Date;
/**
 * Created with IntelliJ IDEA.
 * @Description: Jwt工具类
 */
@Slf4j
@Data
@Component
@ConfigurationProperties(prefix = "validation.jwt")
public class JwtUtil {
    /**
     * 密钥
     */
    private String secretKey;

    /**
     * Token有效时间
     */
    //private long effectiveTime;

    /** @Description: 根据Claim信息生成JSON WEB TOKEN
     * 在jwt中存储的一些非隐私信息
    * @Param: [id, phone]
    * @return: java.lang.String
    * @Author: jack
    * @Date: 2022/10/30
    */
    public String getToken(String id) throws UnsupportedEncodingException {
        long currentTimeMillis = System.currentTimeMillis();
        //Date expireTime = new Date(System.currentTimeMillis() + effectiveTime);
        return JWT.create()
                //生成的是不带-的字符串，类似于：b17f24ff026d40949c85a24f4f375d42
                //String simpleUUID = IdUtil.simpleUUID();
                .withJWTId(IdUtil.simpleUUID())//签发一个id
                .withSubject("username")//签发人，也就是JWT是给谁的（逻辑上一般都是username或者userId
                .withIssuedAt(new Date(currentTimeMillis))//签发日期，换算当前系统时间生成的iat
                //.withExpiresAt(expireTime)//过期时间
                .withSubject("sub")//设置主题
                .withClaim("userId",id)//设置载荷Payload，也就是Claims部分
                .sign(Algorithm.HMAC256(secretKey));//设置签名
    }
    /** @Description: 校验token是否合法,是否过期，必须都满足才返回true
    * @Param: [token]
    * @return: boolean
    * @Author: jack
    * @Date: 2022/10/30
    */
    public boolean verify(String token) {
        try{
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secretKey)).build();
            verifier.verify(token);// 校验不通过会抛出异常
            return true;//能走走到这里代表两点：1. 头部和荷载部分没有篡改过 2. 没有过期
        }catch (IllegalArgumentException e) {
            log.info("IllegalArgumentException,token非法");
            return false;
        } catch (JWTVerificationException e) {
            log.info("JWTVerificationException,token已过期");
            return false;
        } catch (UnsupportedEncodingException e) {
            throw new RuntimeException(e);
        }
    }

    public DecodedJWT getClaimByToken(String token) {
        try {
            JWTVerifier verifier = JWT.require(Algorithm.HMAC256(secretKey)).build();
            return verifier.verify(token);//这个返回对象里面包含了jwt的一切信息
        }catch (Exception e){
            log.debug("解析token出错", e);
            return null;
        }
    }
    /** @Description: 无需解密直接获取token的存入的某个Claim
     * @Param: [token]
     * @return: java.lang.String
     * @Author: jack
     * @Date: 2022/10/30
     */
    public String getToken2(String token) {
        try {
            DecodedJWT jwt = JWT.decode(token);
            return jwt.getClaim("userId").asString();
        } catch (JWTDecodeException e) {
            log.info("token错误");
            return e.getMessage();
        }
    }
}